import my.common.File;
import my.epoll.EventArray;
import my.epoll.Native;
import my.socket.ServerSocket;
import my.socket.Socket;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.StandardCharsets;

public class EpollMain {

    static {
        System.load(BioMain.class.getResource("/").getPath() + "libepoll-http.so");
    }

    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8080);
        EventArray events = new EventArray(1024);

        int efd = Native.epollCreate();
        Native.epollCtlAdd(efd, serverSocket.intValue(), Native.EPOLLIN);
        for (;;) {
            int len = Native.epollWait(efd, events, 0);
            for (int i = 0; i < len; i++) {
                int fd = events.fd(i);
                if (serverSocket.intValue() == fd) {
                    Socket socket = serverSocket.accept();
                    Native.epollCtlAdd(efd, socket.intValue(), Native.EPOLLIN | Native.EPOLLET);
                } else {
                    ByteBuffer buf = ByteBuffer.allocateDirect(10);
                    StringBuilder sb = new StringBuilder();
                    if ((events.events(i) & Native.EPOLLIN) != 0) {
                        for (;;) {
                            int read = File.read(fd, buf, buf.position(), buf.limit());
                            if (read < 0) {
                                break;
                            }
                            buf.position(read);
                            buf.flip();
                            try {
                                String request = StandardCharsets.UTF_8.newDecoder().decode(buf).toString();
                                sb.append(request);
                            } catch (CharacterCodingException e) {
                                e.printStackTrace();
                            }
                            buf.clear();
                        }
                        System.out.print(sb.toString());
                        Native.epollCtlMod(efd, fd, Native.EPOLLOUT);
                    } else if ((events.events(i) & Native.EPOLLOUT) != 0) {
                        String response = "respon\n";
                        buf.put(response.getBytes());
                        buf.flip();
                        File.write(fd, buf, buf.position(), buf.limit());
                        Native.epollCtlMod(efd, fd, Native.EPOLLIN);
                    }
                }
            }
        }
    }
}
